#include "configure.h"
#include <fstream>
#include <cassert>

namespace cores
{
    namespace common
    {
        namespace configures
        {
            Configure *Configure::globalInstance = nullptr;

            Configure::Configure()
            {
                if (Configure::globalInstance == nullptr)
                    Configure::globalInstance = this;
            }

            Configure::~Configure()
            {
                for (auto &config : _configItems)
                {
                    delete config.second;
                }
                _configItems.clear();

                if (Configure::globalInstance == this)
                    Configure::globalInstance = nullptr;
            }

            void Configure::LoadConfigInfo()
            {
                if (Configure::globalInstance == nullptr)
                    return;

                Configure::globalInstance->loadConfigInfo();
            }

            string Configure::toString(const string &name)
            {
                if (Configure::globalInstance == nullptr)
                    assert(false);

                if (Configure::globalInstance->_configItems.count(name) == 0)
                    assert(false);

                return Configure::globalInstance->_configItems[name]->toString();
            }

            int Configure::toInt(const string &name)
            {
                if (Configure::globalInstance == nullptr)
                    assert(false);

                if (Configure::globalInstance->_configItems.count(name) == 0)
                    assert(false);

                return Configure::globalInstance->_configItems[name]->toInt();
            }

            double Configure::toDouble(const string &name)
            {
                if (Configure::globalInstance == nullptr)
                    assert(false);

                if (Configure::globalInstance->_configItems.count(name) == 0)
                    assert(false);

                return Configure::globalInstance->_configItems[name]->toDouble();
            }

            bool Configure::toBool(const string& name)
            {
                if (Configure::globalInstance == nullptr)
                    assert(false);

                if (Configure::globalInstance->_configItems.count(name) == 0)
                    assert(false);

                return Configure::globalInstance->_configItems[name]->toBool();
            }

            void Configure::setValue(const string& name, const string& value)
            {
                if (Configure::globalInstance == nullptr)
                    assert(false);

                Configure::globalInstance->addConfigItem(name, value);
            }

            void Configure::setValue(const string& name, const int& value)
            {
                if (Configure::globalInstance == nullptr)
                    assert(false);

                Configure::globalInstance->addConfigItem(name, value);
            }

            void Configure::setValue(const string& name, const double& value)
            {
                if (Configure::globalInstance == nullptr)
                    assert(false);

                Configure::globalInstance->addConfigItem(name, value);
            }

            void Configure::setValue(const string& name, const bool& value)
            {
                if (Configure::globalInstance == nullptr)
                    assert(false);

                Configure::globalInstance->addConfigItem(name, value);
            }

            void Configure::addConfigItem(const string &name, const string& value)
            {
                if (this->_configItems.count(name) > 0)
                {
                    delete this->_configItems[name];
                }

                this->_configItems[name] = new StringValue(value);
            }

            void Configure::addConfigItem(const string &name, const int& value)
            {
                if (this->_configItems.count(name) > 0)
                {
                    delete this->_configItems[name];
                }

                this->_configItems[name] = new IntValue(value);
            }

            void Configure::addConfigItem(const string &name, const double& value)
            {
                if (this->_configItems.count(name) > 0)
                {
                    delete this->_configItems[name];
                }

                this->_configItems[name] = new DoubleValue(value);
            }

            void Configure::addConfigItem(const string &name, const bool& value)
            {
                if (this->_configItems.count(name) > 0)
                {
                    delete this->_configItems[name];
                }

                this->_configItems[name] = new BoolValue(value);
            }
        }

    }
}